﻿using eBus;
using mLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace eBus_boot_serial
{
    public partial class Form1 : Form
    {

        eBus_core ebus;
        eBus_boot ebus_boot;
        List<byte> ebus_read_mem_buff;

        public int read_write_now_sit = 0;


        #region 提示信息输出相关
        public void msgoutx(String str,int[] value)
        {

            if (ebus_boot != null)switch (ebus_boot.eBus_boot_now_state)
            {
                case eBus_boot.eBus_boot_State_enum.eBus_boot_State_read:
                    if (str.IndexOf("eBus_boot_read_mem") == -1) break;
                    if (value == null) break;
                    if (value.Length != 2) break;
                    read_write_now_sit = value[0] + value[1];
                    break;
                case eBus_boot.eBus_boot_State_enum.eBus_boot_State_write:
                    if (str.IndexOf("eBus_boot_write_mem") == -1) break;
                    if (value == null) break;
                    if (value.Length != 2) break;
                    read_write_now_sit = value[0] + value[1];
                    break;
                default: break;
            }
            msgout(str,OUTTYPE.none);
        }
        public void msgout(String str, Color color, Color backcolor)
        {
            try
            {
                if (richTextBox1.InvokeRequired)
                {
                    // 当一个控件的InvokeRequired属性值为真时，说明有一个创建它以外的线程想访问它
                    Action<string> actionDelegate = (x) =>
                    {

                        richTextBox1.SelectionColor = color;
                        richTextBox1.SelectionBackColor = backcolor;
                        this.richTextBox1.AppendText(x);
                    };
                    this.richTextBox1.Invoke(actionDelegate, str);
                }
                else
                {
                    richTextBox1.SelectionColor = color;
                    richTextBox1.SelectionBackColor = backcolor;
                    this.richTextBox1.AppendText(str);
                    this.richTextBox1.Focus();//获取焦点
                    this.richTextBox1.Select(this.richTextBox1.TextLength, 0);//光标定位到文本最后
                    this.richTextBox1.ScrollToCaret();//滚动到光标处
                }
            }
            catch
            { 
            
            }

        }
        public enum OUTTYPE
        {
            none = 0,
            hint,
            warning,
            error

        };
        public void msgout(String str, OUTTYPE type = OUTTYPE.none)
        {
            //DateTime time = new DateTime();
            //time=System.DateTime.Now;
            //str = time.Hour.ToString() + ":" + time.Minute.ToString() + ":" + time.Second.ToString() + ":" + str;
            switch (type)
            {
                case OUTTYPE.none: msgout(str, Color.Black, Color.FromArgb(240, 240, 240)); break;
                case OUTTYPE.hint: msgout(str, Color.Black, Color.Lime); break;
                case OUTTYPE.warning: msgout(str, Color.Black, Color.Orange); break;
                case OUTTYPE.error: msgout(str, Color.Black, Color.Red); break;
                default: msgout(str, Color.Black, Color.LightSlateGray); break;
            }
        }
        public void msgout(String str, OUTTYPE type, Boolean timeE)
        {
            if (timeE == true)
            {
                DateTime time = new DateTime();
                time = System.DateTime.Now;
                str = "\r\n" + time.Hour.ToString() + ":" + time.Minute.ToString() + ":" + time.Second.ToString() + ":" + str;
            }
            switch (type)
            {
                case OUTTYPE.none: msgout(str, Color.Black, Color.FromArgb(240, 240, 240)); break;
                case OUTTYPE.hint: msgout(str, Color.Black, Color.Lime); break;
                case OUTTYPE.warning: msgout(str, Color.Black, Color.Orange); break;
                case OUTTYPE.error: msgout(str, Color.Black, Color.Red); break;
                default: msgout(str, Color.Black, Color.LightSlateGray); break;
            }
        }
        public void msgout_Cleare()
        {
            richTextBox1.Clear();
        }
        private void richTextBox1_DoubleClick(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            richTextBox1.SelectionStart = richTextBox1.TextLength;
            richTextBox1.ScrollToCaret();
        }
        #endregion

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ChuanKou_Auto();

            ebus = new eBus_core(chuankou_send_bytes);
            ebus_boot = new eBus_boot(ebus.eBus_pack_send_flow, msgoutx, ebus_read_mem_event);

            ebus.eBus_subscribe_pack(ebus_boot.eBus_boot_receive);
        }

        private void ebus_read_mem_event(List<byte> btl)
        {
            ebus_read_mem_buff = btl;
        }


        public String com_x = "";
        private void ChuanKou_Auto()
        {
            int i = 0;
            string[] str = System.IO.Ports.SerialPort.GetPortNames();     //获取电脑上已有串口 
            cb_port.Items.Clear();//清除所有选项
            if (str.Length != 0)
            {
                try
                {
                    for (i = 0; i < str.Length; i++)
                    {
                        cb_port.Items.Add(str[i]);
                    }
                }
                catch
                {
                    cb_port.Items.Add("无端口");
                }
            }
            else
            {
                cb_port.Items.Add("无端口");
            }
            int index = cb_port.FindString(com_x, 0);
            if (index != -1)
            {
                cb_port.SelectedIndex = index;
            }
            else cb_port.SelectedIndex = 0;
        }

        private void bt_onoff_Click(object sender, EventArgs e)
        {
            if (chuankou.IsOpen == false)
            {
                chuankou.PortName = cb_port.Text;
                chuankou.BaudRate = 500000;
                chuankou.DataBits = 8;
                chuankou.Parity = Parity.None;
                chuankou.StopBits = StopBits.One;
                chuankou.ReadBufferSize = 102400;
                try
                {
                    chuankou.Open();
                    bt_onoff.BackColor = Color.FromArgb(0, 255, 0);
                    bt_onoff.Text = "关闭串口";
                    msgout_Cleare();
                    msgout("串口打开\r\n", OUTTYPE.hint);
                }
                catch (InvalidOperationException)
                {
                    msgout("串口已经被打开，请不要重复打开\r\n", OUTTYPE.error);
                }
                catch (UnauthorizedAccessException)
                {
                    msgout("串口拒绝访问，请检查是否已经被其它应用打开\r\n", OUTTYPE.error);
                }
                catch (System.IO.IOException)
                {
                    msgout("参数设置错误\r\n", OUTTYPE.error);
                }
                catch
                {
                    msgout("串口打开出错，请检查原因\r\n", OUTTYPE.error);
                }
            }
            else if (chuankou.IsOpen == true)
            {
                bt_onoff.BackColor = Color.FromArgb(200, 125, 0);
                bt_onoff.Text = "打开串口";
                chuankou.Close();
                msgout("串口已关闭\r\n", OUTTYPE.hint);
            }
        }
        private void chuankou_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                while (chuankou.BytesToRead > 0)
                {
                    byte[] bts = new byte[chuankou.BytesToRead];
                    chuankou.Read(bts, 0, bts.Length);
                    ebus.eBus_flow_add(bts);
                }
                Thread.Sleep(2);
            }
            catch
            {

            }
        }

        private void chuankou_send_bytes(List<byte> btl)
        {
            if (btl == null || btl.Count == 0) return;
            chuankou.Write(btl.ToArray(), 0, btl.Count);
        }
        private void updata_pct_Tick(object sender, EventArgs e)
        {
            File_Operate_PCT.Value = read_write_now_sit;
            file_update_dis.Text = File_Operate_PCT.Value.ToString()+"/"+File_Operate_PCT.Maximum.ToString();
        }

        private void app_updata_Click(object sender, EventArgs e)
        {
            
            List<byte> flashWriteData = new List<byte>();
            String filename = "";
            if (Function.File2Bytes(null, "程序文件(*.bin)|" + "*.bin", ref flashWriteData, ref filename))
            {
                read_write_now_sit = 0;
                File_Operate_PCT.Value = 0;
                File_Operate_PCT.Minimum = 0;
                File_Operate_PCT.Maximum = flashWriteData.Count;
                updata_pct.Enabled = true;
                ebus_boot.eBus_boot_write_mem_start(flashWriteData.ToArray(),512);
                msgout("准备升级，等待设备上电或复位\r\n", OUTTYPE.hint);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
        }

        byte[] bts_buff = new byte[16 * 1024];
        private void button2_Click(object sender, EventArgs e)
        {
            msgout("准备读取，等待设备上电或复位\r\n", OUTTYPE.hint);
            read_write_now_sit = 0;
            File_Operate_PCT.Value = 0;
            File_Operate_PCT.Minimum = 0;
            File_Operate_PCT.Maximum = 16 * 1024;
            ebus_boot.eBus_boot_read_mem_start(0, 1024, 16 * 1024);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Function.Bytes2File(null, null, Text, ebus_read_mem_buff.ToArray());
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ebus_boot.eBus_boot_reset();
        }






    }
}
